package top.hcode.hoj.controller.admin;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.nutz.filepool.FilePool;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.dao.collect.ItechCollDao;
import top.hcode.hoj.manager.coll.ItechCollQuestionJudgeManger;
import top.hcode.hoj.pojo.dto.BaseIdDTO;
import top.hcode.hoj.pojo.dto.OptionDTO;
import top.hcode.hoj.pojo.dto.QuerySampleDTO;
import top.hcode.hoj.pojo.dto.coll.*;
import top.hcode.hoj.pojo.entity.coll.ItechCollection;
import top.hcode.hoj.pojo.vo.coll.CollSubjectiveQuestionToJudgeVO;
import top.hcode.hoj.pojo.vo.coll.ItechCollStudentScoreDetailVO;
import top.hcode.hoj.pojo.vo.coll.ItechCollectionStatVO;
import top.hcode.hoj.service.UserAuthService;
import top.hcode.hoj.service.admin.AdminCollUserAnswerService;
import top.hcode.hoj.service.admin.AdminItechCollectionService;
import top.hcode.hoj.utils.ShiroUtils;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 调研活动管理接口
 *
 * @author orangej
 * @since 2025-01-21
 */
@Slf4j
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class AdminItechCollController {

    private final FilePool filePool;
    private final ItechCollDao collDao;

    private final AdminItechCollectionService itechCollService;
    private final AdminCollUserAnswerService userAnswerService;
    private final UserAuthService userAuthService;
    private final ItechCollQuestionJudgeManger judgeManger;

    @ApiOperation(value = "获取调研活动列表")
    @GetMapping("/admin/itech-coll/list")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    public CommonResult<IPage<ItechCollection>> getItechCollectionList(QuerySampleDTO querySampleDTO) {
        return CommonResult.successResponse(itechCollService.getItechCollectionList(querySampleDTO));
    }

    @ApiOperation(value = "获取调研活动详情")
    @GetMapping("/admin/itech-coll/detail")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    public CommonResult<ItechCollection> getItechCollection(Long id) {
        return CommonResult.successResponse(itechCollService.getItechCollection(id));
    }

    @ApiOperation(value = "保存调研活动")
    @PostMapping("/admin/itech-coll/save")
    @RequiresRoles("teacher")
    public CommonResult<ItechCollection> saveItechCollection(@RequestBody ItechCollection itechCollection) {
        return CommonResult.successResponse(itechCollService.saveItechCollection(itechCollection));
    }

    @ApiOperation(value = "删除调研活动")
    @PostMapping("/admin/itech-coll/delete")
    @RequiresRoles("teacher")
    public CommonResult<Void> deleteItechCollection(@RequestBody BaseIdDTO dto) {
        itechCollService.deleteItechCollection(dto.getId());
        return CommonResult.successResponse();
    }

    @ApiOperation(value = "复制调研活动")
    @PostMapping("/admin/itech-coll/copy")
    @RequiresRoles("teacher")
    public CommonResult<Void> copyItechCollection(@RequestBody ItechCollCopyDTO dto) {
        itechCollService.copyItechCollection(dto);
        return CommonResult.successResponse();
    }

    @ApiOperation(value = "生成模拟答题数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "collId", value = "调研活动ID", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "count", value = "生成数量", required = false, dataType = "Integer", paramType = "query")
    })
    @GetMapping("/admin/itech-coll/mock-answers")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    public CommonResult<Void> mockAnswers(@NotNull String collId, Integer count) {
        userAnswerService.mockAnswers(collId, count);
        return CommonResult.successResponse();
    }

    @ApiOperation(value = "查询成绩得分统计")
    @GetMapping("/admin/itech-coll/score-stat")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    public CommonResult<ItechCollectionStatVO> getItechCollectionList(QueryItechCollectionStatDTO form) {
        if (form == null || form.getCollId() == null) {
            return CommonResult.successResponse(new ItechCollectionStatVO());
        }

        List<String> schoolIdList = userAuthService.getSchoolIdList();
        return CommonResult.successResponse(itechCollService.getItechCollectionStat(form, schoolIdList));
    }

    @ApiOperation(value = "查询学生成绩列表")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    @GetMapping("/admin/itech-coll/student-score-list")
    public CommonResult<IPage<ItechCollStudentScoreDetailVO>> getItechCollStudentDetailVOList(QueryCollStudentScoreDTO form) {
        if (form == null || form.getCollId() == null) {
            return CommonResult.successResponse(new Page<>());
        }

        IPage<ItechCollStudentScoreDetailVO> pager = itechCollService.queryItechCollStudentScoreList(form, userAuthService.getSchoolIdList());
        if (pager.getRecords().size() > 0) {
            // 隐藏账号
            pager.getRecords().forEach(item -> {
                item.setAccount(null);
            });
        }
        return CommonResult.successResponse(pager);
    }

    @ApiOperation(value = "导出学生成绩列表")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    @GetMapping("/admin/itech-coll/student-score-list/export")
    public CommonResult<String> exportItechCollStudentDetailVOList(@Validated QueryCollStudentScoreDTO form) {
        return CommonResult.successResponse(itechCollService.exportItechCollStudentScoreList(form, userAuthService.getSchoolIdList()), "success");
    }

    @ApiOperation(value = "查询单个学生成绩详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "学生id", required = true, dataType = "String", paramType = "query"),
    })
    @RequiresAuthentication
    @RequiresRoles("teacher")
    @GetMapping("/admin/itech-coll/student-score-detail")
    public CommonResult<ItechCollStudentScoreDetailVO> getItechCollStudentDetail(String userId) {
        return CommonResult.successResponse(itechCollService.getItechCollStudentScoreDetail(userId));
    }

    @ApiOperation(value = "查询题目列表（包括学生答案）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "学生id", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "collId", value = "活动id", required = true, dataType = "String", paramType = "query"),
    })
    @RequiresAuthentication
    @RequiresRoles("teacher")
    @GetMapping("/admin/itech-coll/question-list-with-user-answer")
    public CommonResult<List<CollQuestionWithUserAnswerVO>> queryCollQuestionWithUserAnswerList(@NotNull String userId, @NotNull String collId) {
        return CommonResult.successResponse(userAnswerService.queryCollQuestionWithUserAnswerList(userId, collId));
    }

    @ApiOperation(value = "获取下一个待评分的主观题信息")
    @GetMapping("/admin/itech-coll/next-subjective-question-to-judge")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    public CommonResult<CollSubjectiveQuestionToJudgeVO> getNextSubjectiveQuestion(@Validated QueryNextSubjectiveQuestionToJudgeDTO form) {
        String teacher = ShiroUtils.getUid();
        return CommonResult.successResponse(userAnswerService.getNextSubjectiveQuestionToJudge(teacher, form));
    }

    @ApiOperation(value = "主观题判分")
    @PostMapping("/admin/itech-coll/judge-question")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    public CommonResult<Void> judgeQuestionAnswer(@Validated @RequestBody ItechCollJudgeQuestionDTO dto) {
        String teacher = ShiroUtils.getUid();
        judgeManger.judgeSubjective(teacher, dto);
        return CommonResult.successResponse();
    }

    @ApiOperation(value = "对考试所有客观题判分")
    @PostMapping("/admin/itech-coll/judge-all-objective-question")
    @RequiresAuthentication
    @RequiresRoles("root")
    public CommonResult<Void> judgeObjectiveQuestionAnswer(@Validated @RequestBody BaseIdDTO dto) {
        String collId = String.valueOf(dto.getId());
        judgeManger.judgeAllObjective(collId);
        return CommonResult.successResponse();
    }

    @ApiOperation(value = "获取调研活动列表（选项）")
    @GetMapping("/admin/itech-coll/options")
    @RequiresAuthentication
    @RequiresRoles("teacher")
    public CommonResult<List<OptionDTO>> getOptions() {
        List<String> schoolIdList = userAuthService.getSchoolIdList();
        String username = userAuthService.username();

        List<ItechCollection> collList = itechCollService.queryBySchools(schoolIdList);
        if (!userAuthService.isRoot()) {
            collList = collList.stream()
                    .filter(item -> {
                        if (BooleanUtil.isFalse(item.getEnabled())) {
                            return false;
                        }

                        // 所有教师可见
                        if (StrUtil.isBlank(item.getTeacherList())) {
                            return true;
                        }

                        // 部分教师可见
                        return item.getTeacherList().contains(username);
                    }).collect(Collectors.toList());
        }

        List<OptionDTO> optionList = collList.stream()
                .map(it -> new OptionDTO(it.getCollTitle(), it.getId()))
                .collect(Collectors.toList());

        return CommonResult.successResponse(optionList);
    }

}
